<?php


namespace App\Kuafu\CouponPackage\Service;

use App\Kuafu\Base\Service\BaseService;
use App\Kuafu\Common\Service\CommonService;
use App\Kuafu\Coupon\Enum\CouponEnum;
use App\Kuafu\Coupon\Exceptions\CouponException;
use App\Kuafu\CustomerCoupon\Enum\CodeEnum;
use App\Kuafu\Holiday\Service\HolidayService;
use App\Kuafu\Shop\Service\ShopService;
use Illuminate\Support\Facades\Log;

class CouponPackageEnableCouponService extends BaseService
{

    /**
     * @var array 不可用优惠券列表
     */
    private array $canNotUseCouponList = [];

    /**
     * 可用优惠券列表
     * @var
     */
    private array $canUseCouponList = [];

    /**
     * @return array
     */
    public function getCanNotUseCouponList(): array
    {
        return $this->canNotUseCouponList;
    }

    /**
     * @param array $canNotUseCouponList
     */
    public function setCanNotUseCouponList(array $canNotUseCouponList): void
    {
        $this->canNotUseCouponList = $canNotUseCouponList;
    }

    /**
     * @return mixed
     */
    public function getCanUseCouponList(): array
    {
        return $this->canUseCouponList;
    }

    /**
     * @param mixed $canUseCouponList
     */
    public function setCanUseCouponList(array $canUseCouponList): void
    {
        $this->canUseCouponList = $canUseCouponList;
    }

    /**
     * @var array 商品分摊信息
     */
    private array $productList = [];

    private $source;

    /**
     * @var int 已经抵扣的金额
     */
    private $totalCondition = 0;

    public function __construct($brandId, $shopId, $productList, $source, $couponPackageId)
    {
        parent::__construct($brandId, $shopId);
        $this->productList      = $productList;
        $this->canUseCouponList = CouponPackageService::dateToChangeCouponPackaggeList($couponPackageId);
        $this->source           = CodeEnum::CouponSourceChange($source);
    }

    /**
     *
     */
    public function filterCouponPackageCoupon()
    {
        //过滤不可用平台
        $this->filterCustomerCouponSource();
        //过滤有效期
        $this->filterCustomerCouponEffective();
        //过滤不可用店铺
        $this->filterCustomerCouponShop();
        //过滤不可用日期
        $this->filterCustomerCouponDate();
        //过滤不可用时间
        $this->filterCustomerCouponTime();
        //过滤不可用产品
        $this->filterCustomerCouponProduct();
        //过滤金额不可用
        $this->filterCustomerCouponMoney();
        //过滤成本
        $this->filterCustomerCouponPrice();
        return $this;
    }


    public function filterCustomerCouponEffective()
    {
        $canUseCouponList    = $this->canUseCouponList;
        $canNotUseCouponList = $this->canNotUseCouponList;//不可用优惠券列表
        $time                = time();
        foreach ($canUseCouponList as $key => $value) {
            //使用有效期  1 固定时间 2 相对时间
            if ($value['useTimeType'] == 1) {
                //固定时间
                $startAt = $value['startAt'];
                $endAt   = $value['endAt'];
            } else {
                //相对时间
                $startAt = strtotime($value['createdAt']) + $value['startAt'] * 86400;
                $endAt   = strtotime($value['createdAt']) + ($value['startAt'] + $value['endAt']) * 86400;
            }
            if ($time <= $startAt || $time >= $endAt) {
                Log::info('不在使用有效期');
                $canNotUseCouponList[] = $value;
                unset($canUseCouponList[$key]);

            }
        }
        $this->canNotUseCouponList = $canNotUseCouponList;
        $this->canUseCouponList    = $canUseCouponList;
        return $this;
    }


    /**
     * 过滤不可用平台
     * @param $key
     * @param $value
     * @param $canUseCouponList
     */
    public function filterCustomerCouponSource()
    {
        $canUseCouponList    = $this->canUseCouponList;
        $canNotUseCouponList = $this->canNotUseCouponList;//不可用优惠券列表
        foreach ($canUseCouponList as $key => $value) {
            if ($value['availableSource'] > 0) {
                $decodeRules = CommonService::decodeRules($value['availableSource']);
                if (!in_array($this->source, $decodeRules)) {
                    Log::info("获取券包优惠券列表错误-{$value['name']}", ['msg' => '平台不可用']);
                    $canNotUseCouponList[] = $value;
                    unset($canUseCouponList[$key]);
                }
            }
        }
        $this->canNotUseCouponList = $canNotUseCouponList;
        $this->canUseCouponList    = $canUseCouponList;
        return $this;
    }

    /**
     * 过滤店铺
     * @param $shopId
     */
    public function filterCustomerCouponShop()
    {
        $canUseCouponList = $this->canUseCouponList;
        //获取店铺基本信息
        $shopInfo            = ShopService::getShopInfo($this->shopId);
        $canNotUseCouponList = $this->canNotUseCouponList;//不可用优惠券列表
        foreach ($canUseCouponList as $key => $value) {
            switch ($value['shopType']) {
                case CodeEnum::COUPON_SHOP_TYPE_JOIN:
                    //过滤非加盟
                    if ($shopInfo['type'] != CodeEnum::COUPON_SHOP_TYPE_JOIN) {
                        Log::info("获取券包优惠券列表错误-{$value['name']}", ['msg' => '店铺非加盟']);
                        $canNotUseCouponList[] = $value;
                        unset($canUseCouponList[$key]);

                    }
                    break;
                case CodeEnum::COUPON_SHOP_TYPE_DIRECTLY:
                    //t过滤非直营
                    if ($shopInfo['type'] != CodeEnum::COUPON_SHOP_TYPE_DIRECTLY) {
                        Log::info("获取券包优惠券列表错误-{$value['name']}", ['msg' => '店铺非直营']);
                        $canNotUseCouponList[] = $value;
                        unset($canUseCouponList[$key]);

                    }
                    break;
                case CodeEnum::COUPON_SHOP_TYPE_PART:
                    //过滤部分店铺
                    $shopIds = array_column($value['shopRel'], 'shopId');
                    if (!in_array($this->shopId, $shopIds)) {
                        Log::info("获取券包优惠券列表错误-{$value['name']}", ['msg' => '不在可用门店范围']);
                        $canNotUseCouponList[] = $value;
                        unset($canUseCouponList[$key]);
                    }
                    break;
                case CodeEnum::COUPON_SHOP_TYPE_ALl :
                    //全部 不做处理
            }
        }
        $this->canNotUseCouponList = $canNotUseCouponList;
        $this->canUseCouponList    = $canUseCouponList;
        return $this;
    }

    /**
     * 过滤可用商品
     */
    public function filterCustomerCouponProduct()
    {
        $canUseCouponList    = $this->canUseCouponList;
        $productList         = $this->productList;
        $canNotUseCouponList = $this->canNotUseCouponList;//不可用优惠券列表
        //获取产品列表的id集合
        $productListIds = array_column($productList, 'productId');
        foreach ($canUseCouponList as $key => $value) {
            if (!empty($value['canUseProduct'])) {
                if ($value['productUseType'] == CouponEnum::PRODUCT_USE_TYPE_NO) {
                    //不可使用时 先取出数据库不可适用列表
                    $notCanProductIds = explode(',', $value['canUseProduct']);
                    //比较两者差集就是可以使用的
                    $canUserProductIds = array_diff($productListIds, $notCanProductIds);
                } else {
                    $canUserProductIds = explode(',', $value['canUseProduct']);
                }
                //取交集，如果选择的商品不在可用商品范围内，过滤掉不可用的优惠券
                if (empty(array_intersect($productListIds, $canUserProductIds))) {
                    Log::info("获取券包优惠券列表错误-{$value['name']}", ['msg' => '商品不可用']);
                    $canNotUseCouponList[] = $value;
                    unset($canUseCouponList[$key]);
                }
            }
        }
        $this->canNotUseCouponList = $canNotUseCouponList;
        $this->canUseCouponList    = $canUseCouponList;
        return $this;
    }

    /**
     * 过滤日期 周一到周六以及节假日
     */
    public function filterCustomerCouponDate()
    {
        $canUseCouponList    = $this->canUseCouponList;
        $canNotUseCouponList = $this->canNotUseCouponList;//不可用优惠券列表
        //获取星期 1-6表示周一到周六 0 表示周末
        $day  = date("w") != 0 ? date("w") : 7;
        $date = date("Ymd");
        //获取法定节假日
        $holidayConfigList = array_column(HolidayService::getHolidayConfigList(), 'holiday');
        foreach ($canUseCouponList as $key => $value) {
            if (!empty($value['unableDate'])) {
                $notUseDay = explode(',', $value['unableDate']);
                //正常周末判断
                if ($day <= 7 && in_array($day, $notUseDay)) {
                    Log::info("获取券包优惠券列表错误-{$value['id']}", ['msg' => '日期不可用']);
                    $canNotUseCouponList[] = $value;
                    unset($canUseCouponList[$key]);
                    continue;
                }
                //判断法定节假日
                if (in_array(CodeEnum::COUPON_UNABLE_DATE_HOLIDAY, $notUseDay) && in_array($date, $holidayConfigList)) {
                    Log::info("获取券包优惠券列表错误-{$value['name']}", ['msg' => '法定节假日不可用']);
                    $canNotUseCouponList[] = $value;
                    unset($canUseCouponList[$key]);

                }
            }
        }
        $this->canNotUseCouponList = $canNotUseCouponList;
        $this->canUseCouponList    = $canUseCouponList;
        return $this;
    }

    /**
     * 过滤不可用时间
     * @param $type
     * @return $this
     * @throws CouponException
     */
    public function filterCustomerCouponTime()
    {
        $canUseCouponList    = $this->canUseCouponList;
        $canNotUseCouponList = $this->canNotUseCouponList;//不可用优惠券列表
        //获取当前时间
        $time = date('H:i:s');
        list($h, $m, $s) = explode(":", $time);
        $timeInt = ($h * 60 + $m) * 60 + $s;
        foreach ($canUseCouponList as $key => $value) {
            if (!empty($value['unableTime'])) {
                $unableTime = json_decode($value['unableTime'], true);
                foreach ($unableTime as $item) {
                    if ($time >= $item['startAt'] && $time <= $item['endAt']) {
                        Log::info("获取券包优惠券列表错误-{$value['name']}", ['msg' => '时间不可用']);
                        $canNotUseCouponList[] = $value;
                        unset($canUseCouponList[$key]);
                    }
                }
            }
        }
        $this->canNotUseCouponList = $canNotUseCouponList;
        $this->canUseCouponList    = $canUseCouponList;
        return $this;
    }

    /**
     * 过滤商品总金额可用
     * @return $this
     */
    public function filterCustomerCouponMoney()
    {
        $canUseCouponList    = $this->canUseCouponList;
        $productList         = $this->productList;
        $canNotUseCouponList = $this->canNotUseCouponList;//不可用优惠券列表
        $productListIds      = array_column($productList, 'productId');
        foreach ($canUseCouponList as $key => $value) {
            if (!empty($value['useCondition'])) {
                //可以使用的菜品列表集合
                $useProductIds = self::filterCanUseProductIds($value['productUseType'], $productListIds,
                    $value['canUseProduct']);
                $totalMoney    = $this->sumProductTotalMoney($productList, $useProductIds);
                if ($totalMoney - $this->totalCondition < $value['useCondition']) {
                    Log::info("获取券包优惠券列表错误-{$value['name']}", ['msg' => '商品金额不足']);
                    $canNotUseCouponList[] = $value;
                    unset($canUseCouponList[$key]);
                }

            }
        }
        $this->canNotUseCouponList = $canNotUseCouponList;
        $this->canUseCouponList    = $canUseCouponList;
        return $this;
    }


    public function filterCustomerCouponPrice()
    {
        $canUseCouponList    = $this->canUseCouponList;
        $productList         = $this->productList;
        $canNotUseCouponList = $this->canNotUseCouponList;//不可用优惠券列表
        $productListIds      = array_column($productList, 'productId');
        foreach ($canUseCouponList as $key => $value) {
            if ($value['costPrice'] > 0) {
                //可以使用的菜品列表集合
                $useProductIds = self::filterCanUseProductIds($value['productUseType'], $productListIds,
                    $value['canUseProduct']);
                $totalMoney    = $this->sumProductTotalMoney($productList, $useProductIds);
                if ($totalMoney < $value['costPrice']) {
                    //如果是选择，并且总金额减去总抵扣小小于当前券可抵扣
                    Log::info("获取券包优惠券列表错误-{$value['name']}", ['msg' => '成本不可用']);
                    $canNotUseCouponList[] = $value;
                    unset($canUseCouponList[$key]);
                }
            }
        }
        $this->canNotUseCouponList = $canNotUseCouponList;
        $this->canUseCouponList    = $canUseCouponList;
        return $this;
    }

    /**
     * 过滤可用商品列表
     * @param $type
     * @param $productListIds
     * @param $canUseProduct
     * @return array|mixed
     */
    public static function filterCanUseProductIds($type, $productListIds, $canUseProduct)
    {
        if (!empty($canUseProduct)) {
            if ($type == CouponEnum::PRODUCT_USE_TYPE_NO) {
                //不可使用时 先取出数据库不可适用列表
                $notCanProductIds = explode(',', $canUseProduct);
                //比较两者差集就是可以使用的
                $canUseProduct = array_diff($productListIds, $notCanProductIds);
            } else {
                $canUseProduct = explode(',', $canUseProduct);
            }
            //获取菜品交集 走到这一步肯定是有交集的
            return array_intersect($productListIds, $canUseProduct);
        } else {
            return [];
        }
    }

    /**
     * 计算商品总金额
     * @param $productList
     * @param $intersect
     * @return float|int
     */
    public function sumProductTotalMoney($productList, $intersect)
    {
        $total = 0;
        if (empty($intersect)) {
            foreach ($productList as $value) {
                $total += $value['price'] * $value['number'];
            }
        } else {
            foreach ($productList as $value) {
                if (in_array($value['productId'], $intersect)) {
                    $total += $value['price'] * $value['number'];
                }
            }
        }
        return $total;
    }

}